package com.hexacta.hrs.web.struts.actions.security;

import java.security.Security;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.commons.lang.StringUtils;
import org.vectrics.user.Person;
import org.vectrics.user.User;

import com.hexacta.hrs.securitygroups.Permission;
import com.hexacta.hrs.securitygroups.SecurityGroup;
import com.hexacta.hrs.services.crud.CrudService;
import com.hexacta.hrs.services.person.PersonService;
import com.hexacta.hrs.services.securitygroups.SecurityGroupService;
import com.hexacta.hrs.web.struts.actions.CrudAbstractAction;


/**
 * Action de Struts para {@link Security}.
 * 
 * Created on 18/08/2009
 * 
 * @author mtestasecca
 * @author rmilano
 */
public class ManageSecurityGroupAction extends CrudAbstractAction<SecurityGroup> {

    private static final long serialVersionUID = -3546625909116789290L;

    private HashMap<String, String> users;

    private HashMap<String, String> selectedUsers;

    private String[] selectedUsersIds;

    private HashMap<String, String> permissions;

    private HashMap<String, String> selectedPermissions;

    private String[] selectedPermissionsIds;

    private SecurityGroup securityGroup;

    private SecurityGroupService securityGroupsService;
    
    private Set<String> sortedPermissions;
    
    private Set<String> selectedSortedPermissions;

    public void setSecurityGroupsService(SecurityGroupService securityGroupsService) {
        this.securityGroupsService = securityGroupsService;
    }

    private PersonService personService;

    public void setPersonService(PersonService personService) {
        this.personService = personService;
    }

    @Override
    protected CrudService<SecurityGroup> getCrudService() {
        return securityGroupsService;
    }

    /** Obtiene la lista de Usuarios. */
    public HashMap<String, String> getUserNames() {
        users = new HashMap<String, String>();

        Collection<Person> persons = this.personService.getAllPerson();

        for (Person person : persons) {
            if (person.getUser() != null) {
                if (this.securityGroup.getUsers() != null) {
                    if (!this.securityGroup.getUsers().contains(person.getUser())) {
                        users.put(person.getId().toString(), person.getUser().getUserName() + " "
                                + person.getFullName());
                    }
                } else {
                    users.put(person.getId().toString(), person.getUser().getUserName() + " " + person.getFullName());
                }
            }
        }

        return users;
    }

    /** Obtiene la lista de roles de seguridad. */
    public HashMap<String, String> getPermissionsName() {
        this.permissions = new HashMap<String, String>();

        Collection<Permission> permissionsList = securityGroupsService.getAllPermissions();
        for (Permission s : permissionsList) {
            permissions.put(s.getId().toString(), s.getDescription().toString());
        }
        

        // Eliminar elementos incluidos en la lista secundaria.
        if (this.securityGroup.getSecurityGroupRoles() != null) {
            for (Permission s : this.securityGroup.getSecurityGroupRoles()) {
                permissions.remove(s.getId().toString());
            }
        }
        SortedSet<String> sortedset= new TreeSet<String>(this.permissions.values());
        this.setSortedPermissions(sortedset);
        return permissions;
    }

    @Override
    public void validate() {

        // Validaciones de Required
        if (StringUtils.isEmpty(securityGroup.getName())) {
            addFieldError("nameError", "Security Group Name is required");
        }

        if (StringUtils.isEmpty(securityGroup.getDescription())) {
            addFieldError("descriptionError", "Description is required");
        }
    }

    public String validateDelete() {

        boolean proceed = true;
        // Traer elementos del modelo, en este caso hace falta conocer los
        // employees.
        this.getModel();
        if (this.securityGroup.getUsers() != null && this.securityGroup.getUsers().size() > 0) {
            addFieldError("securityGroupError",
                    "Security Group can't be deleted. You need to first remove users from it.");
            proceed = false;
        }

        if (proceed) {
            getCrudService().delete(getModel());
        }
        return list();
    }

    @Override
    public SecurityGroup getModel() {
        this.securityGroup = super.getModel();
        return this.securityGroup;
    }

    @Override
    protected void doActionsBeforeSave() {
        this.securityGroup.getSecurityGroupRoles().clear();
        this.securityGroup.getUsers().clear();
        if (selectedPermissionsIds != null) {
        	int i = 0;
        	String[] permissionsId = new String[100];
        	Collection<Permission> permissions = this.securityGroupsService.getAllPermissions();
        	for (String permission: this.selectedPermissionsIds) {
        		for ( Permission aux: permissions) {
        			if ( permission.equalsIgnoreCase(aux.getDescription())){
        				permissionsId[i] = aux.getId().toString();
        				i++;
        			}
        		}
        	}
        	this.setSelectedPermissionsIds(permissionsId);
            // Agrega los elementos incluidos en la lista secundaria.
            for (String id : this.selectedPermissionsIds) {
            	if ( id != null) {
                this.securityGroup.getSecurityGroupRoles().add(
                        securityGroupsService.getPermissionById(Long.parseLong(id)));
            	}
            }

        }

        if (selectedUsersIds != null) {
            // Agrega los elementos incluidos en la lista secundaria.
            for (String id : selectedUsersIds) {
                Person person = this.personService.getPersonById(Long.parseLong(id));
                this.securityGroup.getUsers().add(person.getUser());
            }
        }

        super.doActionsBeforeSave();
    }

    public HashMap<String, String> getSelectedUserNames() {
        if (this.securityGroup.getUsers() != null) {
            selectedUsers = new HashMap<String, String>();
            for (User user : this.securityGroup.getUsers()) {
                selectedUsers.put(user.getPerson().getId().toString(), user.getPerson().getUser().getUserName() + " "
                        + user.getPerson().getFullName());
            }
        }
        
        return selectedUsers;
    }

    public HashMap<String, String> getSelectedPermissions() {
        if (this.securityGroup.getSecurityGroupRoles() != null) {
            selectedPermissions = new HashMap<String, String>();
            for (Permission s : this.securityGroup.getSecurityGroupRoles()) {
                selectedPermissions.put(s.getId().toString(), s.getName().toString());
            }
        }
        SortedSet<String> sortedset= new TreeSet<String>(this.selectedPermissions.values());
        this.setSelectedSortedPermissions(sortedset);
        return selectedPermissions;
    }

    public void setUserNames(HashMap<String, String> users) {
        this.users = users;
    }

    public String[] getSelectedPermissionsIds() {
        return this.selectedPermissionsIds;
    }

    public void setSelectedPermissionsIds(String[] selectedPermissionsIds) {
        this.selectedPermissionsIds = selectedPermissionsIds;
    }

    public SecurityGroup getSecurityGroup() {
        return securityGroup;
    }

    public void setSecurityGroup(SecurityGroup securityGroup) {
        this.securityGroup = securityGroup;
    }

    public void setSelectedUserNames(HashMap<String, String> selectedUsers) {
        this.selectedUsers = selectedUsers;
    }

    public void setPermissions(HashMap<String, String> permissions) {
        this.permissions = permissions;
    }

    public void setSelectedPermissions(HashMap<String, String> selectedPermissions) {
        this.selectedPermissions = selectedPermissions;
    }

    public String[] getSelectedUserNamesIds() {
        return this.selectedUsersIds;
    }

    public void setSelectedUserNamesIds(String[] selectedUserNamesIds) {
        this.selectedUsersIds = selectedUserNamesIds;
    }

	public void setSortedPermissions(Set<String> sortedPermissions) {
		this.sortedPermissions = sortedPermissions;
	}

	public Set<String> getSortedPermissions() {
		this.getPermissionsName();
		return sortedPermissions;
	}

	public void setSelectedSortedPermissions(
			Set<String> selectedSortedPermissions) {
		this.selectedSortedPermissions = selectedSortedPermissions;
	}

	public Set<String> getSelectedSortedPermissions() {
		this.getSelectedPermissions();
		Set<String> permissionsId = new TreeSet<String>();
		if (selectedSortedPermissions != null) {
        	Collection<Permission> permissions = this.securityGroupsService.getAllPermissions();
        	for (String permission: this.selectedSortedPermissions) {
        		for ( Permission aux: permissions) {
        			if ( permission.equalsIgnoreCase(aux.getName().toString())){
        				permissionsId.add(aux.getDescription().toString());
        			}
        		}
        	}
		}
		this.setSelectedSortedPermissions(permissionsId);
		this.getSecurityGroup();
		return selectedSortedPermissions;
	}

}
